﻿Namespace Audio
	''' <summary>
	''' Extends the NAudio MediaFoundationReader class to allow for looping of the audio.
	''' </summary>
	''' <remarks></remarks>
	Public Class LoopingMediaFoundationReader
		Inherits Global.NAudio.Wave.MediaFoundationReader

		'Private sourceStream As NAudio.Wave.MediaFoundationReader

		''' <summary>
		''' Implements one of the MediaFoundationReader's New Subroutines.
		''' </summary>
		''' <param name="File"></param>
		''' <remarks></remarks>
		Public Sub New(File As String)
			MyBase.New(File)
		End Sub

		''' <summary>
		''' Implements one of the MediaFoundationReader's New Subroutines.
		''' </summary>
		''' <param name="File"></param>
		''' <param name="Settings"></param>
		''' <remarks></remarks>
		Public Sub New(File As String, Settings As MediaFoundationReaderSettings)
			MyBase.New(File, Settings)
		End Sub

		''' <summary>
		''' When set to true the reader will loop through the audio file repeatedly.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property EnableLooping As Boolean
			Get
				Return EnableLoopingProperty
			End Get
			Set(value As Boolean)
				EnableLoopingProperty = value
			End Set
		End Property

		''' <summary>
		''' Represents the EnableLooping Property.
		''' </summary>
		''' <remarks></remarks>
		Private EnableLoopingProperty As Boolean = False

		''' <summary>
		''' Sets the point that the reader will start at.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property StartTime As TimeSpan
			Get
				Return StartTimeProperty
			End Get
			Set(value As TimeSpan)
				If StartTimeProperty <> value Then
					StartTimeProperty = value
					MyBase.CurrentTime = StartTime
				End If
			End Set
		End Property

		Private StartTimeProperty As New TimeSpan(0)

		''' <summary>
		''' Overrides the MediaFoundationReader's Read function to allow for looping the audio cue if EnableLooping is set to true.
		''' </summary>
		''' <param name="buffer"></param>
		''' <param name="offset"></param>
		''' <param name="count"></param>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Overrides Function Read(buffer() As Byte, offset As Integer, count As Integer) As Integer
			Dim totalBytesRead As Integer = 0
			While totalBytesRead < count
				Try
					Dim bytesRead As Integer = MyBase.Read(buffer, offset + totalBytesRead, count - totalBytesRead)
					If bytesRead = 0 Then
						If MyBase.Position = 0 OrElse Not EnableLooping Then
							'Something went wrong
							Exit While
						End If
						'MyBase.Position = 0 'Replaced 2/22/15
						MyBase.CurrentTime = StartTime
					End If
					totalBytesRead += bytesRead
				Catch
				End Try
			End While
			RaiseEvent DoRead(Me, New EventArgs)
			Return totalBytesRead
		End Function

		Public Event DoRead(sender As Object, e As EventArgs)

	End Class
End Namespace